<script setup>
import HomeHead from "@/components/HomeHead.vue";
import NewsItem from "@/components/NewsItem.vue";
import { reactive, onBeforeMount, ref, onMounted, onBeforeUnmount } from "vue";
import { queryNewsLatest, queryNewsBefore } from "@/api";
import { formatTime } from "@/assets/utils";

// 初始化状态
let state = reactive({
  today: formatTime(null, "{0}{1}{2}"),
  bannerList: [],
  newsList: [],
});
let loadingBox = ref(null);

// 第一次渲染之前：从服务器获取今日新闻的相关数据
onBeforeMount(async () => {
  try {
    let { date, stories, top_stories } = await queryNewsLatest();
    state.today = date;
    state.bannerList = top_stories;
    state.newsList.push({
      date,
      stories,
    });
  } catch (_) {}
});

// 第一次渲染完毕：创建监听器，监听Loading盒子是否出现在可视窗口中，从而完成触底加载
let ob;
onMounted(() => {
  ob = new IntersectionObserver(async (changes) => {
    let item = changes[0];
    if (item.isIntersecting) {
      // 出现在可视窗口中：从服务器获取前一天的新闻
      try {
        let arr = state.newsList;
        let result = await queryNewsBefore(arr[arr.length - 1]["date"]);
        state.newsList.push(result);
      } catch (_) {}
    }
  });
  ob.observe(loadingBox.value);
});

// 组件释放之前：手动移除自己设定的定时器/监听器/事件绑定「优化」
onBeforeUnmount(() => {
  if (ob) {
    ob.unobserve(loadingBox.value);
    ob = null;
  }
});
</script>

<script>
export default {
  name: "HomePage",
};
</script>

<template>
  <!-- 头部区域 -->
  <home-head :today="state.today" />

  <!-- 轮播图 -->
  <section class="banner-box">
    <van-swipe
      loop
      lazy-render
      :autoplay="3000"
      v-if="state.bannerList.length > 0"
    >
      <van-swipe-item v-for="item in state.bannerList" :key="item.id">
        <router-link :to="`/detail/${item.id}`">
          <img :src="item.image" alt="" class="pic" />
          <div class="desc">
            <h3 class="title">{{ item.title }}</h3>
            <p class="author">{{ item.hint }}</p>
          </div>
        </router-link>
      </van-swipe-item>
    </van-swipe>
  </section>

  <!-- 新闻列表 -->
  <van-skeleton
    title
    :row="5"
    v-if="state.newsList.length === 0"
  ></van-skeleton>
  <template v-else>
    <section
      class="news-box"
      v-for="(item, index) in state.newsList"
      :key="item.date"
    >
      <van-divider content-position="left" v-if="index > 0">
        {{ formatTime(item.date, "{1}月{2}日") }}
      </van-divider>
      <div class="content">
        <news-item v-for="cur in item.stories" :key="cur.id" :info="cur" />
      </div>
    </section>
  </template>

  <!-- 加载更多 -->
  <div class="lazy-more" ref="loadingBox" v-show="state.newsList.length > 0">
    <van-loading size="12px">小主，精彩数据准备中...</van-loading>
  </div>
</template>

<style lang="less" scoped>
.banner-box {
  box-sizing: border-box;
  height: 375px;
  background: #eee;
  overflow: hidden;

  .van-swipe {
    height: 100%;

    a {
      display: block;
      height: 100%;
    }

    .pic {
      display: block;
      width: 100%;
      height: 100%;
    }

    .desc {
      position: absolute;
      bottom: 0;
      left: 0;
      box-sizing: border-box;
      padding: 20px;
      width: 100%;
      background: rgba(0, 0, 0, 0.5);
      background: -webkit-linear-gradient(
        top,
        rgba(0, 0, 0, 0),
        rgba(0, 0, 0, 0.5)
      );

      .title {
        line-height: 25px;
        font-size: 20px;
        color: #fff;
      }

      .author {
        line-height: 30px;
        font-size: 14px;
        color: rgba(255, 255, 255, 0.7);
      }
    }
  }

  :deep(.van-swipe__indicators) {
    left: auto;
    right: 20px;
    transform: none;

    .van-swipe__indicator--active {
      background-color: #fff;
      width: 18px;
      border-radius: 3px;
    }
  }
}

.news-box {
  padding: 0 15px;

  .van-divider {
    margin: 5px 0;
    font-size: 12px;

    &:before {
      display: none;
    }
  }
}

.van-skeleton {
  padding: 30px 15px;
}

.lazy-more {
  display: flex;
  justify-content: center;
  align-items: center;
  box-sizing: border-box;
  padding: 0 10px;
  height: 50px;
  background: #f4f4f4;
}
</style>